// 文件路径: dbms/ui/UdfManagerStage.java
package com.dbms.ui;

import com.dbms.service.AIService;
import com.dbms.service.IDbmsService;
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon;
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.LineNumberFactory;
import javafx.scene.control.Separator;

/**
 * 一个用于动态定义和注册用户自定义函数 (UDF) 的新窗口。
 * 提供UI界面让用户输入函数信息、编写UDF代码，或通过自然语言描述由AI生成代码，
 * 最终完成UDF的编译和注册流程。
 */
public class UdfManagerStage extends Stage {

    // 数据库服务接口，用于执行UDF注册等核心操作
    private final IDbmsService dbmsService;
    // 代码编辑区域，支持行号显示，用于编写UDF的Java源代码
    private final CodeArea codeArea;
    // 函数名称输入框，用于指定UDF在SQL中使用的名称
    private final TextField functionNameField;
    // 状态标签，用于显示操作结果或错误信息
    private final Label statusLabel;
    // 注册按钮，触发UDF的编译和注册流程
    private final Button registerButton;

    // 【新增】AI相关UI组件
    // 自然语言输入区，用于描述用户需要的UDF功能
    private final TextArea naturalLanguageArea;
    // AI生成按钮，触发AI根据自然语言描述生成UDF代码
    private final Button aiGenerateButton;
    // AI服务实例，用于调用AI生成代码的核心逻辑
    private final AIService aiService;

    // 为用户提供的UDF代码模板
    // 包含必要的包导入、类结构和示例方法，引导用户正确编写UDF
    private static final String UDF_TEMPLATE =
            "package com.dbms.udf.temp;\n\n" +
                    "import com.dbms.execution.udf.Udf;\n\n" +
                    "// 1. 您的类名必须是 'CustomUdf'\n" +
                    "// 2. 必须实现 Udf 接口\n" +
                    "public class CustomUdf implements Udf {\n\n" +
                    "    @Override\n" +
                    "    public Object execute(Object... args) throws Exception {\n" +
                    "        // 3. 在这里编写您的函数逻辑\n" +
                    "        if (args.length != 1 || !(args[0] instanceof String)) {\n" +
                    "            throw new IllegalArgumentException(\"请输入一个字符串参数\");\n" +
                    "        }\n" +
                    "        String input = (String) args[0];\n" +
                    "        // 示例：返回字符串的反转形式\n" +
                    "        return new StringBuilder(input).reverse().toString();\n" +
                    "    }\n" +
                    "}\n";


    /**
     * 构造方法，初始化UDF管理器窗口
     * @param owner 父窗口（通常为主窗口）
     * @param dbmsService 数据库服务实例，用于注册UDF
     */
    public UdfManagerStage(Stage owner, IDbmsService dbmsService) {
        this.dbmsService = dbmsService;
        this.aiService = new AIService(); // 【新增】初始化AI服务，用于代码生成
        initOwner(owner); // 设置父窗口
        // 设置为模态窗口（阻塞父窗口操作，直到当前窗口关闭）
        initModality(Modality.APPLICATION_MODAL);
        setTitle("UDF 管理器"); // 设置窗口标题

        // 主布局容器，采用边界布局（上下左右中五个区域）
        BorderPane root = new BorderPane();
        root.setPadding(new Insets(10)); // 内边距，使内容不紧贴边框

        // --- 表单部分（中间区域）---
        // 垂直布局容器，用于按顺序排列表单组件
        VBox formPane = new VBox(10); // 组件间垂直间距为10
        formPane.setPadding(new Insets(5)); // 内边距

        // 【新增】自然语言输入区相关组件
        Label nlLabel = new Label("用自然语言描述您的函数需求:");
        naturalLanguageArea = new TextArea();
        naturalLanguageArea.setPromptText("例如: 创建一个函数，接收一个字符串，返回它的MD5哈希值");
        naturalLanguageArea.setWrapText(true); // 自动换行
        naturalLanguageArea.setPrefRowCount(3); // 默认显示3行

        // 【新增】AI生成按钮
        aiGenerateButton = new Button("使用 AI 生成代码");
        // 设置按钮图标为魔法图标，直观表示AI生成功能
        aiGenerateButton.setGraphic(new FontAwesomeIconView(FontAwesomeIcon.MAGIC));
        // 绑定点击事件到AI生成逻辑
        aiGenerateButton.setOnAction(e -> handleAiGenerate());

        // 函数名称输入区
        Label nameLabel = new Label("函数SQL名称 (例如: REVERSE):");
        functionNameField = new TextField();
        functionNameField.setPromptText("例如: REVERSE"); // 提示文本

        // 代码编辑区
        Label codeLabel = new Label("UDF Java 源代码 (类名必须为 CustomUdf):");
        codeArea = new CodeArea();
        // 为代码区添加行号显示
        codeArea.setParagraphGraphicFactory(LineNumberFactory.get(codeArea));
        codeArea.replaceText(0, 0, UDF_TEMPLATE); // 初始载入模板代码
        // 可以在这里添加语法高亮，为简化暂时省略
        // codeArea.multiPlainChanges()
        //         .successionEnds(Duration.ofMillis(200))
        //         .subscribe(ignore -> codeArea.setStyleSpans(0, computeHighlighting(codeArea.getText())));

        // 【修改】将所有UI组件按顺序添加到表单容器
        formPane.getChildren().addAll(nlLabel, naturalLanguageArea, aiGenerateButton,
                new Separator(), nameLabel, functionNameField,
                codeLabel, codeArea);

        // --- 底部按钮和状态栏 ---
        VBox bottomPane = new VBox(10); // 垂直布局，组件间距10
        bottomPane.setPadding(new Insets(10, 5, 5, 5)); // 内边距（上右下左）
        registerButton = new Button("编译并注册函数"); // 注册按钮
        statusLabel = new Label("请填写函数名和代码。"); // 初始状态提示
        statusLabel.getStyleClass().add("status-bar"); // 添加CSS样式类
        bottomPane.getChildren().addAll(registerButton, statusLabel); // 添加到底部容器

        // 组装主布局
        root.setCenter(formPane); // 中间区域放表单
        root.setBottom(bottomPane); // 底部区域放按钮和状态栏

        // --- 事件处理 ---
        // 绑定注册按钮点击事件到注册逻辑
        registerButton.setOnAction(e -> handleRegister());

        // 创建场景并设置到窗口
        Scene scene = new Scene(root, 700, 650); // 窗口大小：宽700，高650
        // 复用主窗口的CSS样式表
        scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm());
        setScene(scene);
    }

    /**
     * 【新增】处理AI生成按钮的点击事件
     * 从自然语言输入区获取描述，调用AI服务生成代码，并将结果填充到代码编辑区
     */
    private void handleAiGenerate() {
        // 获取用户输入的自然语言描述
        String description = naturalLanguageArea.getText();
        // 验证输入不为空
        if (description == null || description.trim().isEmpty()) {
            updateStatus("错误: 请先输入您的函数需求描述！", true);
            return;
        }

        // 禁用相关按钮，防止重复操作
        aiGenerateButton.setDisable(true);
        registerButton.setDisable(true);
        // 更新状态提示
        updateStatus("正在请求AI生成代码，请稍候...", false);

        // 启动新线程处理AI调用（避免阻塞UI线程）
        new Thread(() -> {
            // 在后台线程中调用AI服务生成代码
            String generatedCode = aiService.generateUdfCode(description);

            // 切换回JavaFX应用线程更新UI（UI操作必须在主线程执行）
            Platform.runLater(() -> {
                // 处理生成结果
                if (generatedCode.startsWith("错误:")) {
                    // 生成失败，显示错误信息
                    updateStatus(generatedCode, true);
                } else {
                    // 生成成功，将代码填充到编辑区
                    codeArea.replaceText(generatedCode);
                    updateStatus("AI代码已生成，请审核后注册。", false);
                }
                // 恢复按钮可用状态
                aiGenerateButton.setDisable(false);
                registerButton.setDisable(false);
            });
        }).start();
    }

    /**
     * 处理注册按钮的点击事件
     * 验证输入的函数名和代码，调用数据库服务注册UDF，并显示操作结果
     */
    private void handleRegister() {
        // 获取用户输入的函数名和代码
        String functionName = functionNameField.getText();
        String sourceCode = codeArea.getText();

        // 验证函数名不为空
        if (functionName == null || functionName.trim().isEmpty()) {
            updateStatus("错误: 函数SQL名称不能为空！", true);
            return;
        }

        // 验证代码不为空
        if (sourceCode == null || sourceCode.trim().isEmpty()) {
            updateStatus("错误: 源代码不能为空！", true);
            return;
        }

        // 禁用注册按钮，防止重复提交
        registerButton.setDisable(true);
        updateStatus("正在编译和注册...", false);

        // 启动新线程处理注册逻辑（避免阻塞UI）
        new Thread(() -> {
            // 【核心修改】调用服务层方法执行UDF注册
            String result = dbmsService.registerUdf(functionName, sourceCode);
            // 判断是否为错误结果（根据返回信息格式约定）
            boolean isError = !result.startsWith("成功");

            // 切换回UI线程更新状态
            Platform.runLater(() -> {
                updateStatus(result, isError);
                // 恢复按钮可用状态
                registerButton.setDisable(false);
            });
        }).start();
    }

    /**
     * 更新状态标签的显示内容和样式
     * @param message 要显示的状态信息
     * @param isError 是否为错误信息（决定显示样式）
     */
    private void updateStatus(String message, boolean isError) {
        statusLabel.setText(message); // 更新文本内容

        // 先移除已有的状态样式类
        statusLabel.getStyleClass().remove("success-label");
        statusLabel.getStyleClass().remove("error-label");

        // 根据是否为错误添加对应的样式类
        if (isError) {
            statusLabel.getStyleClass().add("error-label"); // 错误样式（通常为红色）
        } else {
            statusLabel.getStyleClass().add("success-label"); // 成功样式（通常为绿色）
        }
    }
}